package com.mystnihon.freeremote.manager.file;

import java.io.File;
import java.io.FilenameFilter;
import java.text.Collator;
import java.text.ParseException;
import java.text.RuleBasedCollator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Locale;
import java.util.TreeSet;

import android.content.Context;
import android.os.Environment;

public class FileManager {

	private File mCurrentDirectory;

	public FileManager(Context context) throws NotMountedStorageException {

		if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
				|| Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {

		} else {
			throw new NotMountedStorageException("The sotrage is not mounted", Environment.getExternalStorageState());
		}

	}

	public File getExternalStorageDirectory() {
		return Environment.getExternalStorageDirectory();
	}

	public ArrayList<File> listDirectoryFile(File file, Comparator<File> comparator) {
		if (file.isDirectory()) {
			mCurrentDirectory = file;
			return sortFile(file.listFiles(), comparator);
		}
		return null;
	}

	public ArrayList<File> listDirectoryFile(File file) {
		if (file.isDirectory()) {
			mCurrentDirectory = file;
			return sortFile(file.listFiles(), new NameFileComparator());
		}
		return null;
	}

	public ArrayList<File> listDirectoryFile(File file, FilenameFilter filter) {
		if (file.isDirectory()) {
			mCurrentDirectory = file;
			return sortFile(file.listFiles(filter), new NameFileComparator());

		}
		return null;
	}

	public ArrayList<File> listExternalStorageBaseFile() {
		return listDirectoryFile(getExternalStorageDirectory(), new NameFileComparator());
	}

	public ArrayList<File> listExternalStorageBaseFile(FilenameFilter filter) {
		return listDirectoryFile(getExternalStorageDirectory(), filter);
	}

	public ArrayList<File> sortFile(File[] files, Comparator<File> comparator) {
		TreeSet<File> set = new TreeSet<File>(comparator);
		if (files != null) {
			HashSet<File> hash = new HashSet<File>(files.length + 10);

			for (File file : files) {
				hash.add(file);
			}
			set.addAll(hash);
		}
		return new ArrayList<File>(set);

	}

	public File getCurrentDirectory() {
		return mCurrentDirectory;
	}

	class DefaultFileComparator implements Comparator<File> {

		@Override
		public int compare(File file1, File file2) {

			return file1.compareTo(file2);
		}

	}

	class NameFileComparator implements Comparator<File> {
		String rule = "< .< _< a,A< b,B< c,C< d,D< e,E< f,F< g,G< h,H< i,I"
				+ "< j,J< k,K< l,L< m,M< n,N< o,O< p,P< q,Q< r,R" + "< s,S< t,T< u,U< v,V< w,W< x,X< y,Y< z,Z";
		Collator mCollator;

		public NameFileComparator(Collator customCollator) {
			mCollator = customCollator;

		}

		public NameFileComparator() {

			try {
				mCollator = new RuleBasedCollator(rule);
			} catch (ParseException e) {
				mCollator = Collator.getInstance(Locale.getDefault());
			}
		}

		@Override
		public int compare(File file1, File file2) {
			if (file1.isDirectory() && !file2.isDirectory()) {
				return -1;
			} else if (!file1.isDirectory() && file2.isDirectory()) {
				return 1;
			} else {
				return mCollator.compare(file1.getName(), file2.getName());
			}
		}

	}

	class SizeFileComparator extends NameFileComparator {

		@Override
		public int compare(File file1, File file2) {

			if (file1.isDirectory() && !file2.isDirectory()) {
				return 1;
			} else if (!file1.isDirectory() && file2.isDirectory()) {
				return -1;
			} else if (file1.isDirectory() && file2.isDirectory()) {
				return super.compare(file1, file2);
			} else {
				if (file1.length() > file2.length()) {
					return 1;
				} else if (file1.length() < file2.length()) {
					return -1;
				}
			}

			return super.compare(file1, file2);
		}
	}

	public static class NameFilter implements FilenameFilter {
		String mfilter;

		public NameFilter(String filter) {
			mfilter = filter;
		}

		@Override
		public boolean accept(File dir, String filename) {
			if (new File(dir, filename).isDirectory()) {
				return true;
			}
			if (filename.contains(mfilter)) {
				return true;
			}
			return false;
		}

	}

	public static FilenameFilter directoryOnly = new FilenameFilter() {

		@Override
		public boolean accept(File dir, String filename) {
			if (new File(dir, filename).isDirectory()) {
				return true;
			}
			return false;
		}

	};

	public static FilenameFilter torrentFilter = new FilenameFilter() {

		@Override
		public boolean accept(File dir, String filename) {
			if (new File(dir, filename).isDirectory()) {
				return true;
			}
			if (filename.endsWith(".torrent")) {
				return true;
			}
			return false;
		}

	};

}
